classdef configManager < handle
    % configManager - 项目配置文件管理工具类
    % 提供统一的配置文件读取、解析和文件打开功能
    %
    % 功能:
    %   - 读取和解析project_config.yml配置文件
    %   - 获取指定配置项的值
    %   - 跨平台文件打开功能
    %   - 路径处理工具
    %
    % 使用示例:
    %   % 获取配置值并打开文件
    %   [success, errorMsg] = configManager.openConfiguredFile('icd_excel_path', 'ICD文件');
    %   
    %   % 只获取配置值
    %   [configValue, errorMsg] = configManager.getConfigValue('system_architecture_path');
    %
    % 作者: MBD Platform
    % 日期: 2025-09-14
    % 版本: 1.0
    
    properties (Constant, Access = private)
        CONFIG_FILE_NAME = 'project_config.yml'
    end
    
    methods (Static, Access = public)
        
        function [success, errorMsg] = openConfiguredFile(configKey, fileDescription)
            % openConfiguredFile - 根据配置文件中的路径打开文件
            % 输入参数:
            %   configKey       - 配置项的键名
            %   fileDescription - 文件描述（用于错误信息）
            % 输出参数:
            %   success   - 逻辑值，true表示成功，false表示失败
            %   errorMsg  - 字符串，错误信息（成功时为空）
            
            success = false;
            errorMsg = '';
            
            try
                % 获取配置文件中的路径
                [filePath, errorMsg] = configManager.getConfigValue(configKey);
                if ~isempty(errorMsg)
                    return;
                end
                
                % 转换为绝对路径
                absolutePath = configManager.toAbsolutePath(filePath);
                
                % 检查文件是否存在
                if ~exist(absolutePath, 'file')
                    errorMsg = sprintf('%s文件不存在: %s', fileDescription, absolutePath);
                    return;
                end
                
                % 打开文件
                [success, errorMsg] = configManager.openFileWithSystem(absolutePath);
                if ~success
                    errorMsg = sprintf('无法打开%s: %s', fileDescription, errorMsg);
                end
                
            catch ME
                errorMsg = sprintf('打开%s过程中发生异常: %s', fileDescription, ME.message);
            end
        end
        
        function [configValue, errorMsg] = getConfigValue(configKey)
            % getConfigValue - 从配置文件中获取指定配置项的值（使用专业YAML工具）
            % 输入参数:
            %   configKey - 配置项的键名
            % 输出参数:
            %   configValue - 配置项的值
            %   errorMsg    - 错误信息（成功时为空）
            
            configValue = '';
            errorMsg = '';
            
            try
                % 读取配置文件
                configPath = configManager.getConfigFilePath();
                if ~exist(configPath, 'file')
                    errorMsg = sprintf('配置文件不存在: %s', configPath);
                    return;
                end
                
                % 使用专业的yamlread工具解析配置文件（项目会自动添加yamltool路径）
                configData = yamlread(configPath);
                
                if isempty(configData)
                    errorMsg = '配置文件为空或格式无效';
                    return;
                end
                
                % 从解析后的数据结构中获取配置值
                if isfield(configData, configKey)
                    configValue = configData.(configKey);
                    % 如果配置值是字符串，移除引号（如果存在）
                    if ischar(configValue) || isstring(configValue)
                        configValue = configManager.removeQuotes(char(configValue));
                    end
                else
                    errorMsg = sprintf('配置文件中未找到%s设置', configKey);
                end
                
            catch ME
                errorMsg = sprintf('读取配置文件过程中发生异常: %s', ME.message);
            end
        end
        
        function [success, errorMsg] = openFileWithSystem(filePath)
            % openFileWithSystem - 使用系统默认程序打开文件
            % 输入参数:
            %   filePath - 要打开的文件路径
            % 输出参数:
            %   success  - 逻辑值，true表示成功，false表示失败
            %   errorMsg - 错误信息（成功时为空）
            
            success = false;
            errorMsg = '';
            
            try
                % 使用系统默认程序打开文件
                if ispc
                    [status, ~] = system(['start "" "' filePath '"']);
                elseif ismac
                    [status, ~] = system(['open "' filePath '"']);
                else
                    [status, ~] = system(['xdg-open "' filePath '"']);
                end
                
                if status ~= 0
                    errorMsg = sprintf('系统命令执行失败，无法打开文件: %s', filePath);
                    return;
                end
                
                success = true;
                
            catch ME
                errorMsg = sprintf('打开文件过程中发生异常: %s', ME.message);
            end
        end
        
        function result = isAbsolutePath(pathStr)
            % isAbsolutePath - 判断路径是否为绝对路径
            % 输入: pathStr - 待检查的路径字符串
            % 输出: result - true表示绝对路径，false表示相对路径
            
            if isempty(pathStr)
                result = false;
                return;
            end
            
            % Windows系统：检查是否以驱动器字母开头（如C:\）或UNC路径（\\）
            if ispc
                result = (length(pathStr) >= 3 && pathStr(2) == ':') || ...
                         (length(pathStr) >= 2 && strcmp(pathStr(1:2), '\\'));
            else
                % Unix/Linux/Mac系统：检查是否以/开头
                result = pathStr(1) == '/';
            end
        end
        
        function absolutePath = toAbsolutePath(pathStr)
            % toAbsolutePath - 将相对路径转换为绝对路径
            % 输入: pathStr - 路径字符串
            % 输出: absolutePath - 绝对路径
            
            if configManager.isAbsolutePath(pathStr)
                absolutePath = pathStr;
            else
                absolutePath = fullfile(pwd, pathStr);
            end
        end
        
    end
    
    methods (Static, Access = private)
        
        function configPath = getConfigFilePath()
            % getConfigFilePath - 获取配置文件的完整路径
            % 输出: configPath - 配置文件路径
            
            configDir = ProjectPathManager.getDirPath('project configuration root');
            configPath = fullfile(configDir, configManager.CONFIG_FILE_NAME);
        end
        
        function cleanValue = removeQuotes(value)
            % removeQuotes - 移除字符串两端的引号
            % 输入: value - 原始字符串
            % 输出: cleanValue - 移除引号后的字符串
            
            cleanValue = value;
            if (startsWith(cleanValue, '"') && endsWith(cleanValue, '"')) || ...
               (startsWith(cleanValue, '''') && endsWith(cleanValue, ''''))
                cleanValue = cleanValue(2:end-1);
            end
        end
        
    end
end
